# -*- coding:utf-8 -*-
import time
import requests

from datetime import datetime, timedelta
from helper.jd_logger import logger
from helper.config import global_config
from helper.jd_helper import (
    parse_json
)


class Timer(object):
    def __init__(self, sleep_interval=0.5):
        # '2018-09-28 22:45:50.000'
        # buy_time = 2020-12-22 09:59:59.500
        self.localtime = time.localtime(time.time())
        self.buy_period = global_config.getRaw('config', 'buy_period').__str__().split(";")
        # buy_time_everyday = global_config.getRaw('config', 'buy_time').__str__()
        # last_purchase_time_everyday = global_config.getRaw('config', 'last_purchase_time').__str__()
        self.buy_time, self.buy_time_ms = self.get_buy_time()
        self.sleep_interval = sleep_interval
        self.diff_time = self.local_jd_time_diff()

    def get_buy_time(self):
        buy_time = None
        for t in self.buy_period:
            json_t = parse_json(t)
            self.buy_time_config = datetime.strptime(
                self.localtime.tm_year.__str__() + '-' + self.localtime.tm_mon.__str__() + '-' + self.localtime.tm_mday.__str__()
                + ' ' + json_t["start_time"], "%Y-%m-%d %H:%M:%S.%f")
            # 最后购买时间
            self.last_purchase_time = datetime.strptime(
                self.localtime.tm_year.__str__() + '-' + self.localtime.tm_mon.__str__() + '-' + self.localtime.tm_mday.__str__()
                + ' ' + json_t["end_time"], "%Y-%m-%d %H:%M:%S.%f")
            # print(f"最后购买时间：{self.last_purchase_time}")
            # print("localtime=", time.mktime(self.localtime))
            # print(time.mktime(buy_time_config.timetuple()))

            if time.mktime(self.localtime) < time.mktime(self.buy_time_config.timetuple()):
                # 取正确的购买时间
                buy_time = self.buy_time_config
                break
        if buy_time is None:
            buy_time = datetime.strptime(
                self.localtime.tm_year.__str__() + '-' + self.localtime.tm_mon.__str__() + '-' + (
                        self.localtime.tm_mday + 1).__str__() + ' ' + parse_json(self.buy_period[0])["start_time"],
                "%Y-%m-%d %H:%M:%S.%f")

        # logger.info("购买时间：{}".format(buy_time))
        # logger.info("最后购买时间：{}".format(self.last_purchase_time))
        buy_time_ms = int(time.mktime(buy_time.timetuple()) * 1000.0 + buy_time.microsecond / 1000)
        return buy_time, buy_time_ms

    def jd_time(self):
        """
        从京东服务器获取时间毫秒
        :return:
        """
        # url = 'https://a.jd.com//ajax/queryServerData.html'
        # ret = requests.get(url).text
        # js = json.loads(ret)
        # return int(js["serverTime"])
        url = 'https://api.m.jd.com'
        resp = requests.get(url)
        jd_timestamp = int(resp.headers.get('X-API-Request-Id')[-13:])
        return jd_timestamp

    def local_time(self):
        """
        获取本地毫秒时间
        :return:
        """
        return int(round(time.time() * 1000))

    def local_jd_time_diff(self):
        """
        计算本地与京东服务器时间差
        :return:
        """
        return self.local_time() - self.jd_time()

    def start(self):
        logger.info('正在等待到达设定时间:{}，检测本地时间与京东服务器时间误差为【{}】毫秒'.format(self.buy_time, self.diff_time))
        while True:
            # 本地时间减去与京东的时间差，能够将时间误差提升到0.1秒附近
            # 具体精度依赖获取京东服务器时间的网络时间损耗
            if self.local_time() - self.diff_time >= self.buy_time_ms:
                logger.info('时间到达，开始执行……')
                break
            else:
                time.sleep(self.sleep_interval)

    def is_end(self, seckill_time=5):
        """
        秒杀时长
        """
        localtime = datetime.now()
        localtime_stamp=localtime.timestamp()
        end_time = (self.buy_time_config + timedelta(seconds=seckill_time))
        end_time_stamp=end_time.timestamp()
        # print(f"self.localtime_stamp={localtime_stamp},self.end_time_stamp={end_time_stamp}")
        diff = end_time_stamp - localtime_stamp
        # print(diff)
        # print(diff.seconds)
        if diff < 0:
            return True
        return False
